<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/entities/Entity.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/entities/Process.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/entities/Indicator.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/model/Service/Service.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/model/DAO/IndicatorDAO.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/exceptions/DataBaseException.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/utils/Str.php';

class IndicatorDAOImpl extends IndicatorDAO {
	 
	public function create(Entity $indicator) {
/*		$sql = 'INSERT INTO `indicator` (`name`,`weight`,`is_objective`,`year`,`plan_value`';
		
		if($indicator->getParent() !== null) {
			$sql .= ',`id_parent`';
		}
		
		$sql .= ',`id_unit`,`id_process`';
		$sql .= ') VALUES ("'.$indicator->getName().'"';
		$sql .= ','.$indicator->getWeight();
		$sql .= ','.$indicator->isObjective();
		$sql .= ','.$indicator->getYear();
		
		if($indicator->getPlanValue() !== null) {
			$sql .= ','.$indicator->getPlanValue();
		} else $sql .= ',NULL';	
				
		if($indicator->getParent() !== null) {
			$sql .= ','.$indicator->getParent()->getIdentity();
		}
		
		$sql .= ','.$indicator->getUnit()->getIdentity();
		$sql .= ','.$indicator->getProcess()->getIdentity();
		$sql .= ')';
		
		try {
			$this->query($sql);
			$indicator->setIdentity($this->identity());
			return $indicator;
		} catch(DataBaseException $excepton) {
			return null;
		}
*/

		$sql = 'INSERT INTO `indicator` (`name`, `weight`, `is_objective`, `year`, `id_unit`, `id_process`) VALUES(?, ?, ?, ?, ?, ?)';
		if($indicator->getPlanValue() !== null) {
			$sql = 'INSERT INTO `indicator` (`name`, `weight`, `is_objective`, `year`, `plan_value`, `id_unit`, `id_process`) VALUES(?, ?, ?, ?, ?, ?, ?)';
			if($indicator->getParent() !== null) {
				$sql = 'INSERT INTO `indicator` (`name`, `weight`, `is_objective`, `year`, `plan_value`, `id_parent`, `id_unit`, `id_process`) VALUES(?, ?, ?, ?, ?, ?, ?, ?)';			
			}
		} elseif ($indicator->getParent() !== null) {
			$sql = 'INSERT INTO `indicator` (`name`, `weight`, `is_objective`, `year`, `plan_value`, `id_parent`, `id_unit`, `id_process`) VALUES(?, ?, ?, ?, NULL, ?, ?, ?)';
		} else {
			$sql = 'INSERT INTO `indicator` (`name`, `weight`, `is_objective`, `year`, `plan_value`, `id_unit`, `id_process`) VALUES(?, ?, ?, ?, NULL, ?, ?)';
		}			
				
		$name = $indicator->getName();
		$weight = $indicator->getWeight();
		$is_objective = $indicator->isObjective();
		$year = $indicator->getYear();
		$plan_value = $indicator->getPlanValue();
		$parentId = $indicator->getParent()->getIdentity();
		$unitId = $indicator->getUnit()->getIdentity();
		$processId = $indicator->getProcess()->getIdentity();
		
		$stmt = $this->dbh->connection->prepare($sql);
		$stmt->bindValue(1, $name);
		$stmt->bindValue(2, $weight);
		$stmt->bindValue(3, $is_objective);
		$stmt->bindValue(4, $year);
		$stmt->bindValue(5, $unitId);
		$stmt->bindValue(6, $processId);
		
		if($indicator->getPlanValue() !== null) {
			$stmt->bindValue(1, $name);
			$stmt->bindValue(2, $weight);
			$stmt->bindValue(3, $is_objective);
			$stmt->bindValue(4, $year);
			$stmt->bindValue(5, $plan_value);
			$stmt->bindValue(6, $unitId);
			$stmt->bindValue(7, $processId);
			
			if($indicator->getParent() !== null) {
				$stmt->bindValue(1, $name);
				$stmt->bindValue(2, $weight);
				$stmt->bindValue(3, $is_objective);
				$stmt->bindValue(4, $year);
				$stmt->bindValue(5, $plan_value);
				$stmt->bindValue(6, $parentId);
				$stmt->bindValue(7, $unitId);
				$stmt->bindValue(8, $processId);
			}
		} elseif ($indicator->getParent() !== null) {
				$stmt->bindValue(1, $name);
				$stmt->bindValue(2, $weight);
				$stmt->bindValue(3, $is_objective);
				$stmt->bindValue(4, $year);
				$stmt->bindValue(5, $parentId);
				$stmt->bindValue(6, $unitId);
				$stmt->bindValue(7, $processId);
		} else {
				$stmt->bindValue(1, $name);
				$stmt->bindValue(2, $weight);
				$stmt->bindValue(3, $is_objective);
				$stmt->bindValue(4, $year);
				$stmt->bindValue(5, $unitId);
				$stmt->bindValue(6, $processId);
		}
		
		try {
			$this->dbh->query($stmt);
			$indicator->setIdentity($this->dbh->identity());
			return $indicator;
		} catch(PDOException $excepton) {
			return null;
		}
				
	}
	
	private function findIndicator(Indicator $indicator, $identity) {
		if($identity == $indicator->getIdentity()) {
			return $indicator;
		} else {
			$children = $indicator->getChildren();
			if($children !== null) {
				foreach($children as $child) {
					$result = $this->findIndicator($child, $identity);
					if($result !== null) {
						return $result;
					}
				}
			}
		}
		return null;
	}
	
	public function read($identity) {
		$indicators = $this->getAll();

		foreach($indicators as $indicator) {
			$result = $this->findIndicator($indicator, $identity);
			if($result !== null) {
				// удалить потом это!!!
// 				$serviceFactoy = new ServiceFactory(); // Создаем фабрику сервисов
// 				$serviceProcess = $serviceFactoy->getService('ProcessService');// Получаем нужный сервис				
				// это раскомментить, это исходное!!!
				//$serviceProcess = getService('ProcessService');
// 				$serviceProcess = $serviceFactoy->getService('ProcessService');
// 				$process = $serviceProcess->read($result->getProcess()->getIdentity());
				$process = new Process();
				$process->setIdentity($result->getProcess()->getIdentity());
				$result->setProcess($process);
				return $result;
			}
		}
		return null;
	}
	
	public function update(Entity $indicator) {
/*		$sql = 'UPDATE `indicator` ';
		$sql .= 'SET `name`="'.$indicator->getName().'"';
		$sql .= ',`weight`="'.$indicator->getWeight().'"';
		$sql .= ',`is_objective`='.$indicator->isObjective();
		$sql .= ',`year`='.$indicator->getYear();
			
		if($indicator->getPlanValue() !== null) {
			$sql .= ',`plan_value`='.$indicator->getPlanValue();
		} else $sql .= ',`plan_value`=NULL';
		
		if($indicator->getParent() !== null) {
			$sql .= ',`id_parent`='.$indicator->getParent()->getIdentity();
		}
		
		$sql .= ',`id_unit`='.$indicator->getUnit()->getIdentity();
		$sql .= ',`id_process`='.$indicator->getProcess()->getIdentity();
		$sql .= ' WHERE `id`='.$indicator->getIdentity();
		
		try {
			$this->query($sql);
			return $indicator;
		} catch(DataBaseException $excepton) {
			return null;
		}
*/

		$sql = 'UPDATE `indicator` SET `name`=?, `weight`=?, `is_objective`=?, `year`=?, `id_unit`=?, `id_process`=? WHERE `id`=?';
		if($indicator->getPlanValue() !== null) {
			$sql = 'UPDATE `indicator` SET `name`=?, `weight`=?, `is_objective`=?, `year`=?, `plan_value`=?, `id_unit`=?, `id_process`=? WHERE `id`=?';
			if($indicator->getParent() !== null) {
				$sql = 'UPDATE `indicator` SET `name`=?, `weight`=?, `is_objective`=?, `year`=?, `plan_value`=?, `id_parent`=?, `id_unit`=?, `id_process`=? WHERE `id`=?';				
			}
		} elseif ($indicator->getParent() !== null) {
			$sql = 'UPDATE `indicator` SET `name`=?, `weight`=?, `is_objective`=?, `year`=?, `plan_value`=NULL, `id_parent`=?, `id_unit`=?, `id_process`=? WHERE `id`=?';
		} else {
			$sql = 'UPDATE `indicator` SET `name`=?, `weight`=?, `is_objective`=?, `year`=?, `plan_value`=NULL, `id_unit`=?, `id_process`=? WHERE `id`=?';
		}
		
		$name = $indicator->getName();
		$weight = $indicator->getWeight();
		$is_objective = $indicator->isObjective();
		$year = $indicator->getYear();
		$plan_value = $indicator->getPlanValue();
		$parentId = $indicator->getParent()->getIdentity();
		$unitId = $indicator->getUnit()->getIdentity();
		$processId = $indicator->getProcess()->getIdentity();
		$id = ((int)$indicator->getIdentity());
		
		$stmt = $this->dbh->connection->prepare($sql);
		$stmt->bindValue(1, $name);
		$stmt->bindValue(2, $weight);
		$stmt->bindValue(3, $is_objective);
		$stmt->bindValue(4, $year);
		$stmt->bindValue(5, $unitId);
		$stmt->bindValue(6, $processId);
		$stmt->bindValue(7, $id);
		
			if($indicator->getPlanValue() !== null) {
			$stmt->bindValue(1, $name);
			$stmt->bindValue(2, $weight);
			$stmt->bindValue(3, $is_objective);
			$stmt->bindValue(4, $year);
			$stmt->bindValue(5, $plan_value);
			$stmt->bindValue(6, $unitId);
			$stmt->bindValue(7, $processId);
			$stmt->bindValue(8, $id);
			
			if($indicator->getParent() !== null) {
				$stmt->bindValue(1, $name);
				$stmt->bindValue(2, $weight);
				$stmt->bindValue(3, $is_objective);
				$stmt->bindValue(4, $year);
				$stmt->bindValue(5, $plan_value);
				$stmt->bindValue(6, $parentId);
				$stmt->bindValue(7, $unitId);
				$stmt->bindValue(8, $processId);
				$stmt->bindValue(9, $id);
			}
		} elseif ($indicator->getParent() !== null) {
				$stmt->bindValue(1, $name);
				$stmt->bindValue(2, $weight);
				$stmt->bindValue(3, $is_objective);
				$stmt->bindValue(4, $year);
				$stmt->bindValue(5, $parentId);
				$stmt->bindValue(6, $unitId);
				$stmt->bindValue(7, $processId);
				$stmt->bindValue(8, $id);
		} else {
				$stmt->bindValue(1, $name);
				$stmt->bindValue(2, $weight);
				$stmt->bindValue(3, $is_objective);
				$stmt->bindValue(4, $year);
				$stmt->bindValue(5, $unitId);
				$stmt->bindValue(6, $processId);
				$stmt->bindValue(8, $id);
		}
		
		try {
			$this->dbh->query($stmt);
			return $indicator;
		} catch(PDOException $excepton) {
			return null;
		}
		
	}
	
	public function delete($identity) {
/*		$sql = 'DELETE FROM `indicator` ';
		$sql .= 'WHERE `id`='.((int)$identity);
		try {
			$this->query($sql);
			return true;
		} catch(DataBaseException $exception) {
			return false;
		}
*/		
		
		$id = ((int)$identity);
		
		$stmt = $this->dbh->connection->prepare('DELETE FROM `indicator` WHERE `id`=?');
		$stmt->bindValue(1, $id);
		
		try {
			$this->dbh->query($stmt);
			return true;
		} catch (PDOException $exception) {
			return false;
		}
		
	}
	
	public function getIndicatorsForProcess(Process $process){
		$indicators = $this->getAll();
		
		foreach($indicators as $indicator) {
			// массив основных показателей надо передать процессу
			if ($indicator->getProcess()->getIdentity() == $process->getIdentity()){
				$indicator->setProcess($process);
				$process->addIndicator($indicator);
			}
			
		}
	}	

		
	// список родительских показателей
	// подчиненные показатели будут найдены по ним
	private function getAll(){
/*		$sql = 'SELECT `id`,`name`,`weight`,`is_objective`';
		$sql .= ',`year`,`plan_value`,`id_parent`,`id_unit`,`id_process`';
		$sql .= ' FROM `indicator`';
		$this->query($sql);
	
		$allIndicators = array();
	
		$serviceUnit = getService('UnitService');
	
		// 1) сформировали массив allIndicators со всеми показателями, удовлетворяющими условию
		while($row = $this->row()) {
			$indicator = new Indicator();
			$indicator->setIdentity($row['id']);
			$indicator->setName($row['name']);
			$indicator->setWeight($row['weight']);
			$indicator->setObjective($row['is_objective']);
			$indicator->setYear($row['year']);
			$indicator->setPlanValue($row['plan_value']);
	
			// формально создаем родителя заполняя только его id
			if(Str::isNotEmpty($row['id_parent'])) {
				$parent = new Indicator();
				$parent->setIdentity($row['id_parent']);
				$indicator->setParent($parent);
			}
	
			$indicator->setUnit($serviceUnit->read($row['id_unit']));
	
			//формально создаем процесс, которому принадлежит показатель
			$process = new Process();
			$process->setIdentity($row['id_process']);
			$indicator->setProcess($process);
			
			$allIndicators[$indicator->getIdentity()] = $indicator;
		}
		$this->close();
	
		// 2) создаем правильные ссылки на родителя-показателя
		// из числа элементов созданного массива
		foreach($allIndicators as $indicator) {
			$parent = $indicator->getParent();
			if($parent !== null) {
				$parentIdentity = $parent->getIdentity();
				$parent = $allIndicators[$parentIdentity];
				$indicator->setParent($parent);
			}
		}
	
		// 3) родительскому показателю добавляем детей
		// и формируем массив только родительских показателей
		$indicators = array();
		foreach($allIndicators as $indicator) {
			$parent = $indicator->getParent();
			if($parent !== null) {
				$parent->addChild($indicator);
			} else {
				$indicators[] = $indicator;
			}
		}
	return $indicators;
*/	

		$this->dbh->query('SELECT `id`, `name`, `weight`, `is_objective`, `year`, `plan_value`, `id_parent`, `id_unit`, `id_process` FROM `indicator`');
	
		$allIndicators = array();
	
		// удалить потом это!!!
// 		$serviceFactoy = new ServiceFactory(); // Создаем фабрику сервисов
// 		$serviceUnit = $serviceFactoy->getService('UnitService');// Получаем нужный сервис				
		// это раскомментить, это исходное!!!
		//$serviceUnit = getService('UnitService');										
		
		// 1) сформировали массив allIndicators со всеми показателями, удовлетворяющими условию
		while($row = $this->dbh->row()) {
			$indicator = new Indicator();
			$indicator->setIdentity($row['id']);
			$indicator->setName($row['name']);
			$indicator->setWeight($row['weight']);
			$indicator->setObjective($row['is_objective']);
			$indicator->setYear($row['year']);
			$indicator->setPlanValue($row['plan_value']);
		
			// формально создаем родителя заполняя только его id
			if(Str::isNotEmpty($row['id_parent'])) {
				$parent = new Indicator();
				$parent->setIdentity($row['id_parent']);
				$indicator->setParent($parent);
			}if(Str::isNotEmpty($row['id_unit'])) {
				$unit = new Unit();
				$unit->setIdentity($row['id_unit']);
				$indicator->setUnit($unit);
			}
		
// 			$indicator->setUnit($serviceUnit->read($row['id_unit']));
		
			//формально создаем процесс, которому принадлежит показатель
			$process = new Process();
			$process->setIdentity($row['id_process']);
			$indicator->setProcess($process);
				
			$allIndicators[$indicator->getIdentity()] = $indicator;
		}
		$this->dbh->close();
			
		// 2) создаем правильные ссылки на родителя-показателя
		// из числа элементов созданного массива
		foreach($allIndicators as $indicator) {
			$parent = $indicator->getParent();
			if($parent !== null) {
				$parentIdentity = $parent->getIdentity();
				$parent = $allIndicators[$parentIdentity];
				$indicator->setParent($parent);
			}
		}
	
		// 3) родительскому показателю добавляем детей
		// и формируем массив только родительских показателей
		$indicators = array();
		foreach($allIndicators as $indicator) {
			$parent = $indicator->getParent();
			if($parent !== null) {
				$parent->addChild($indicator);
			} else {
				$indicators[] = $indicator;
			}
		}
		return $indicators;
		
	}
	
	//Возвратить сформированные показатели нового года
	public function getAllYear($year,$year2){	
/*		$sql = 'SELECT `name`,`weight`,`is_objective`';
		$sql .= ',`year`,`plan_value`,`id_parent`,`id_unit`,`id_process`';
		$sql .= ' FROM `indicator`';
		$sql .= 'WHERE `year`=';
		$sql .= $year;
		$this->query($sql);
		$serviceUnit = getService('UnitService');
		$allIndicators = array();
		while($row = $this->row()) {
			$indicator = new Indicator();
			//$indicator->setIdentity($row['id']);
			$indicator->setName($row['name']);
			$indicator->setWeight($row['weight']);
			$indicator->setObjective($row['is_objective']);
			//Изменим текущий год на новый
			$indicator->setYear($year2);
			$indicator->setPlanValue($row['plan_value']);
			
				// формально создаем родителя заполняя только его id
			if(Str::isNotEmpty($row['id_parent'])) {
				$parent = new Indicator();
				$parent->setIdentity($row['id_parent']);
				$indicator->setParent($parent);
			}
	
			$indicator->setUnit($serviceUnit->read($row['id_unit']));
	
			//формально создаем процесс, которому принадлежит показатель
			$process = new Process();
			$process->setIdentity($row['id_process']);
			$indicator->setProcess($process);
				$indicators[] = $indicator;
		
		
		}
		$this->close();
		return $indicators;
*/

		$stmt = $this->dbh->connection->prepare('SELECT `id`, `name`, `weight`, `is_objective`, `year`, `plan_value`, `id_parent`, `id_unit`, `id_process` FROM `indicator` WHERE `year`=?');
		$stmt->bindValue(1, $year);			
		$this->dbh->query($stmt);
		
// 		// удалить потом это!!!
// 		$serviceFactoy = new ServiceFactory(); // Создаем фабрику сервисов
// 		$serviceUnit = $serviceFactoy->getService('UnitService');// Получаем нужный сервис		
		// это раскомментить, это исходное!!!
		//$serviceUnit = getService('UnitService');
		$allIndicators = array();
		while($row = $this->dbh->row()) {
			$indicator = new Indicator();
			//$indicator->setIdentity($row['id']);
			$indicator->setName($row['name']);
			$indicator->setWeight($row['weight']);
			$indicator->setObjective($row['is_objective']);
			//Изменим текущий год на новый
			$indicator->setYear($year2);
			$indicator->setPlanValue($row['plan_value']);
				
			// формально создаем родителя заполняя только его id
			if(Str::isNotEmpty($row['id_parent'])) {
				$parent = new Indicator();
				$parent->setIdentity($row['id_parent']);
				$indicator->setParent($parent);
			}if(Str::isNotEmpty($row['id_unit'])) {
				$unit = new Unit();
				$unit->setIdentity($row['id_unit']);
				$indicator->setUnit($unit);
			}
		
// 			$indicator->setUnit($serviceUnit->read($row['id_unit']));
		
			//формально создаем процесс, которому принадлежит показатель
			$process = new Process();
			$process->setIdentity($row['id_process']);
			$indicator->setProcess($process);
			$indicators[] = $indicator;			
		}
		$this->close();
		return $indicators;
		
	}
	
	public function setUnitIndicator($indicators,$units){
		foreach ($indicators as $indicator){
			foreach ($units as $unit){
				if($indicator->getUnit()->getIdentity() === $unit->getIdentity()){
					$indicator->setUnit($unit);
				}
			}
		}
		
	}
	
}

?>